<template>
  <div class="motherboard-wrapper">
    <Header v-if="pageConfig.header" :config="pageConfig.header" :style="pageConfig.header.style"></Header>
    <div class="main-content">
      <!-- 大屏布局 -->
      <lsd-layout v-if="pageConfig.layout">
        <!-- 大屏布局容器 -->
        <template v-for="container in pageConfig.layout.containerList" :key="container.id">
          <!-- 三级组件（详情）布局容器 -->
          <template v-if="container.isDetail">
            <Transition :name="container.transitionType">
              <lsd-layout-container
                v-if="currentDetailConfig[container.type] && currentDetailConfig[container.type].component"
                :id="container.id"
                :ref="container.id"
                :ratio="currentDetailConfig[container.type].parentRatio || container.ratio"
                :direction="container.direction"
                :height="getDomProp(container.height)"
                :width="getDomProp(container.width)"
                :top="getDomProp(container.top)"
                :right="getDomProp(container.right)"
                :bottom="getDomProp(container.bottom)"
                :left="getDomProp(container.left)"
                :style="container.style"
              >
                <async-load-component
                  :component="currentDetailConfig[container.type].component"
                  :key="currentDetailConfig[container.type].component"
                  :detailConfig="detailConfig"
                  :data="currentDetailConfig[container.type].data"
                  :transitionType="container.transitionType"
                  @close="closeDetail(container)"
                />
              </lsd-layout-container>
            </Transition>
          </template>

          <!-- 一级、二级组件容器 -->
          <lsd-layout-container
            v-else
            :id="container.id"
            :ref="container.id"
            :ratio="container.ratio"
            :direction="container.direction"
            :height="getDomProp(container.height)"
            :width="getDomProp(container.width)"
            :top="getDomProp(container.top)"
            :right="getDomProp(container.right)"
            :bottom="getDomProp(container.bottom)"
            :left="getDomProp(container.left)"
            :style="container.style"
          >
            <!-- 二级组件容器 （子路由视图） -->
            <router-view
              v-if="container.type && container.type.includes('child')"
              :spanNum="container.spanNum || pageConfig.layout.spanNumm"
              :transitionType="container.transitionType"
            ></router-view>

            <!-- 一级组件 -->
            <template v-else>
              <!-- 大屏布局子容器 -->
              <lsd-layout-child-container
                v-for="child in container.childList"
                :key="child.id"
                :span="child.span"
                :spanNum="container.spanNum || pageConfig.layout.spanNumm"
                :style="child.style"
              >
                <!-- 业务组件 -->
                <async-load-component
                  v-if="child.component"
                  :class="{
                    active: currentRouteName === child.routeName
                  }"
                  :component="child.component"
                  :key="child.component"
                  :routeName="child.routeName"
                  :config="child"
                  :transitionType="container.transitionType"
                  v-bind="child.componentProps || {}"
                  @handle="handle"
                  @setDetail="setDetail"
                  @close="closeDetail"
                />
              </lsd-layout-child-container>
            </template>
          </lsd-layout-container>
        </template>

        <!-- 底部内容 -->
        <template #main>
          <!-- 地图 -->
          <async-load-component class="map-box" component="map" :config="pageConfig.layout.pageMapConfig" />
        </template>
      </lsd-layout>
      <div class="main-content-l"></div>
      <div class="main-content-r"></div>
    </div>

    <!-- <Loading v-if="isLoading"></Loading> -->
  </div>
</template>

<script setup>
/**
 * 母版
 * @author 朱琦
 * @date   时间：2022/10/19
 */
import { ref, onMounted, watch, computed, markRaw, shallowRef, getCurrentInstance } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from 'vuex'
import AsyncLoadComponent from '../components/AsyncLoadComponent.vue'
import Header from '../components/header'
// import Header from '../../mother-set/modules/default/Header.vue'

import { getPageConfig } from './config'
import Loading from 'bComponent/components/loading'

const route = useRoute()
const router = useRouter()
const store = useStore()
const isLoading = shallowRef(true)
const { proxy } = getCurrentInstance()
// 页面配置
const pageConfig = shallowRef({})
// 是否有菜单组件
const hasMenu = ref(false)
// 当前菜单组件的路由名
const currentRouteName = ref(null)
// 是否有详情
const hasDetail = ref(false)
const currentDetailConfig = ref({
  map: null,
  panel: null
})
// 详情（地图上）配置
const detailMapConfig = ref(null)
// 详情（面板上）配置
const detailPanelConfig = ref(null)

// 详情配置
const detailConfig = computed(() => store.getters['config/detailConfig'])
// 监听路由名
watch(
  () => route.params.routeName,
  val => {
    // 清空详情配置
    setDetailConfig()
    // 获取菜单配置
    getMenuConfig(pageConfig.value.layout)
  }
)
// 监听详情配置
watch(
  detailConfig,
  ({ type, actions, data, config }) => {
    setDetailConfig(config, data)
  },
  {
    deep: true
  }
)

onMounted(() => {
  getData()
})

/**
 * 获取页面配置数据
 */
const getData = () => {
  const config = markRaw(getPageConfig(route.params.pageId))
  currentRouteName.value = route.params.routeName
  pageConfig.value = config
  // 当前页面是否有菜单组件（是就代表有二级）
  hasMenu.value = config.type.includes('menu')
  // 获取当前菜单组件配置
  hasMenu.value && getMenuConfig(config.layout)

  // 保存 页面配置
  store.commit('config/SET_PAGE_CONFIG', config)
}

/**
 * 获取菜单组件配置
 * @param {Object} layout 布局配置
 */
const getMenuConfig = layout => {
  let currentChildConfig = null
  // 遍历布局容器列表，查找菜单组件
  layout.containerList.some(container => {
    // 遍历子容器列表
    return (
      container.childList &&
      container.childList.some(child => {
        // 判断有路由名，子模块列表配置的
        if (child.routeName && child.childList && child.childList.length) {
          // 没有路由名时，默认展示第一个菜单组件子模块
          currentChildConfig || (currentChildConfig = child)
          // 当前路由名存在时
          if (currentRouteName.value) {
            // 判断是否相等
            if (currentRouteName.value === child.routeName) {
              currentChildConfig = child
              return true
            }
            return false
          }
          return true
        }
      })
    )
  })
  // 保存 当前子页面配置
  store.commit('config/SET_PAGE_CHILD_CONFIG', currentChildConfig)

  if (!currentRouteName.value) {
    setRoute(currentChildConfig.routeName)
  }
}

/**
 * 业务组件点击回调-菜单组件
 * @param {String} routeName 路由ming
 */
const handle = routeName => {
  if (route.params.pageId == 'jjj') return
  // 暂时关闭事件切换组件功能
  // if (['event'].includes(routeName)) return
  routeName !== currentRouteName.value && setRoute(routeName)
}

/**
 * 设置路由
 * @param {String} routeName 路由名
 */
const setRoute = routeName => {
  currentRouteName.value = routeName
  router.replace({
    name: 'motherboard-child',
    params: {
      routeName: routeName,
      pageId: route.params.pageId
    },
    query: {
      roadType: store.state.config.roadType,
      areaCode: store.state.config.areaCode
    }
  })
}

/**
 * 详情组件关闭回调
 * @param {*} config
 */
const closeDetail = config => {
  currentDetailConfig.value[config.type] = null
  store.commit('config/SET_DETAIL_CONFIG', {})
}

/**
 * 组件点击设置详情回调
 * @param {Object} data
 */
const setDetail = data => {
  console.log('data', data)
  store.commit('config/SET_DETAIL_CONFIG', markRaw(data))
}

/**
 * 设置当前展示详情配置
 * @param {Array} config 配置
 * @param {Object} data 数据
 */
const setDetailConfig = (config, data) => {
  // 是否有配置
  const hasConfig = config && config.length
  const detail = {}
  if (hasConfig) {
    // 获取对应配置
    config.forEach(item => {
      item.type && (detail[item.type] = { ...item, data })
    })
  }

  // 设置详情配置
  Object.keys(currentDetailConfig.value).forEach(key => {
    currentDetailConfig.value[key] = hasConfig ? detail[key] : null
  })
}

/**
 * 获取dom 属性值
 * @param {Array, String} val 属性值配置
 */
const getDomProp = val => {
  return val instanceof Array ? () => getStyle(val[0], val[1], val[2]) : val
}
/**
 * 根据id获取对应元素的style key值
 * @param {String} id dom id
 * @param {String} type dom 属性类型
 * @param {String} add 增加值（正负值）
 */
const getStyle = (id, type, add = 0) => {
  const dom = document.getElementById(id)
  let num = type.includes('width') ? dom.offsetWidth : dom.offsetHeight
  num = !isNaN(Number(add)) ? num + Number(add) : num
  return num + 'px'
}
</script>

<style scoped lang="less">
@import url(~@/assets/styles/transition.less);

.motherboard-wrapper {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100vw;
  height: 100vh;
  // 禁止选择文字
  user-select: none;

  // background: #e1eafa;
  .main-content {
    flex: 1;
    padding: 20px 60px;
    position: relative;

    .lsd-layout {
      // overflow: inherit;
    }

    .main-content-l,
    .main-content-r {
      position: absolute;
      width: 21px;
      top: 24px;
      bottom: 24px;
    }

    .main-content-l {
      left: 17px;
      background: url(../assets/images/bg-l.png);
      background-size: 100% 100%;
    }

    .main-content-r {
      right: 17px;
      background: url(../assets/images/bg-r.png);
      background-size: 100% 100%;
    }
  }

  .map-box {
    position: fixed;
    top: 60px;
    left: 0;
    right: 0;
    bottom: 0;
  }
}
</style>
